<?php
/**
 * FooImage.php
 * Class to manipulate images with GD or ImageMagick
 * Based on JawsImage from the Jaws Project (http://jaws-project.com)
 *
 * $Id: FooImage.php 14 2007-08-08 06:08:41Z jonathan.hernandez $
 */
class FooImage
{
    private $method;
    
    function __construct($method)
    {
        $this->method = $this->verifyMethod($method);
    }
    
    private function verifyMethod($method)
    {
        switch ($method) {
            case 'ImageMagick':
                if (isset($_ENV['PATH'])) {
                    $path = $_ENV['PATH'];
                } elseif (isset($_SERVER['PATH'])) {
                    $path = $_SERVER['PATH'];
                } else {
                    $path = '/usr/bin:/usr/local/bin:/bin:/usr/X11R6/bin';
                }
                $dirs      = explode(':', $path);
                $exists    = false;
                $dir_count = count($dirs);
                for ($i = 0; $i < $dir_count; $i++) {
                    if (file_exists($dirs[$i].'/convert')) {
                        $exists = true;
                    }
                }

                if ($exists) {
                    return $method;
                }

                return $this->verifyMethod('GD');
                break;
            case 'GD':
                if (function_exists('gd_info')) {
                    return $method;
                }
                return $this->verifyMethod('ImageMagick');
                break;
            default:
                throw new Exception('Invalid method, try: GD or ImageMagick');
                break;
        }
    }

    private function verifyExt($filename)
    {
        // Verify for valid extension
        $ext =  strtolower(substr($filename, strrpos($filename,'.') + 1));
        $valid_extensions = array('jpg', 'jpeg', 'png', 'gif');
        if (in_array($ext, $valid_extensions)) {
            return $ext;
        } else {
            return false;
        }
    }

    public function resize($source, $destiny, $width, $height)
    {
        if (!$ext = $this->verifyExt($source)) {
            throw new Exception ('Invalid image extension');
        }

        switch ($this->method) {
            case 'ImageMagick':
                $csource  = str_replace(' ', '\ ', escapeshellcmd($source));
                $cdestiny = str_replace(' ', '\ ', escapeshellcmd($destiny));
                exec('convert -geometry  '.$width.'x'.$height.' '.$csource.' '.$cdestiny);
                break;
            case 'GD':
                $source_size = getimagesize($source);
                $ratio       =($source_size[0] / $width);
                $h           = round($source_size[1] / $ratio);
                if ($h <= $height) {
                    $w = $width;
                    $destiny_img = imagecreatetruecolor($w, $h);
                } else {
                    $h = $height;
                    $ratio =($source_size[1] / $height);
                    $w = round($source_size[0] / $ratio);
                    $destiny_img = imagecreatetruecolor($w, $h);
                }
                $destiny_img = imagecreatetruecolor($w, $h);
                if ($ext == 'jpeg') {
                    $ext = 'jpg';
                }

                switch ($ext) {
                    case 'jpg':
                        $img = imagecreatefromjpeg($source);
                        imagecopyresampled($destiny_img, $img,
                                       0, 0, 0, 0,
                                       $w, $h,
                                       $source_size[0], $source_size[1]);
                        imagejpeg($destiny_img, $destiny, 100);
                        break;
                    case 'png':
                        $img = imagecreatefrompng($source);
                        imagecopyresampled($destiny_img, $img,
                                       0, 0, 0, 0,
                                       $w, $h,
                                       $source_size[0], $source_size[1]);
                        imagepng($destiny_img, $destiny);
                        break;
                    case 'gif':
                        $img = imagecreatefromgif ($source);
                        imagecopyresampled($destiny_img, $img,
                                       0, 0, 0, 0,
                                       $w, $h,
                                       $source_size[0], $source_size[1]);
                        imagegif ($destiny_img, $destiny);
                        break;
                }
                break;
        }

        if (is_file($destiny)) {
            return true;
        } else {
            throw new Exception ('Image not resized');
        }
    }

    public function resizeSquare($source, $destiny, $size) 
    {
        if (!$ext = $this->verifyExt($source)) {
            throw new Exception ('Invalid image extension');
        }

        switch ($this->method) {
            case 'ImageMagick':
                $csource  = str_replace(' ', '\ ', escapeshellcmd($source));
                $cdestiny = str_replace(' ', '\ ', escapeshellcmd($destiny));
                $aux = $size + ($size / 2);
                exec('convert -geometry '.$aux.'x'.$aux.' -gravity center -crop '.$size.'x'.$size.'+0+0 -quality 91 '.$csource.' '.$cdestiny);
                break;
            case 'GD':
                $destiny_img = imagecreatetruecolor($size, $size);
                $black = imagecolorallocate($destiny_img, 0, 0, 0);
                imagefill($destiny_img, 0, 0, $black);

                $source_size = getimagesize($source);
                $w = $source_size[0];
                $h = $source_size[1];

                if($w > $size && $w > $h){
                    $thumb_hg = $h * ($size / $w);
                    $thumb_wd = $size;
                } elseif($h > $size){
                    $thumb_wd = $w * ($size / $h);
                    $thumb_hg = $h;
                }

                $x = ($size - $thumb_wd) / 2;
                $y = ($size - $thumb_hg) / 2;


                if ($ext == 'jpeg') {
                    $ext = 'jpg';
                }

                switch ($ext) {
                    case 'jpg':
                        $img = imagecreatefromjpeg($source);
                        imagecopyresampled($destiny_img, $img, $x, $y, 0, 0, $thumb_wd, $thumb_hg, $w, $h); 
                        imagejpeg($destiny_img, $destiny, 100);
                        break;
                    case 'png':
                        $img = imagecreatefrompng($source);
                        imagecopyresampled($destiny_img, $img, $x, $y, 0, 0, $thumb_wd, $thumb_hg, $w, $h); 
                        imagepng($destiny_img, $destiny);
                        break;
                    case 'gif':
                        $img = imagecreatefromgif ($source);
                        imagecopyresampled($destiny_img, $img, $x, $y, 0, 0, $thumb_wd, $thumb_hg, $w, $h); 
                        imagegif ($destiny_img, $destiny);
                        break;
                }
                break;
        }

        if (is_file($destiny)) {
            return true;
        } else {
            throw new Exception ('Image not resized');
        }
    }

    public function getEXIFThumbnail($source, $unknown)
    {
        if (strpos($source, '../')) {
            return false;
        }
        $ext       = strtolower(substr($source, strrpos($source,'.')+1));
        $valid_ext = array('jpg', 'jpeg');
        if (in_array($ext, $valid_ext)) {
            if ((function_exists('exif_thumbnail')) && (filesize($source) > 0)) {
                $image = exif_thumbnail($source, $width, $height, $type);
                if ($image !== false) {
                    header('Content-type: ' .image_type_to_mime_type($type));
                    print $image;
                    exit;
                }
            }
        }

        if (is_file($unknown)) {
            $ext = strtolower(substr($unknown, strrpos($unknown,'.')+1));
            header('Content-type: image/'.$ext);
            readfile($unknown);
            exit;
        }

        return false;
    }

    public function getImageSize($filename)
    {
        $size = array();
        $size['width']  = '100%';
        $size['height'] = '100%';

        if (!file_exists($filename)) {
            return $size;
        }

        if (function_exists('getimagesize')) {
            $info = getimagesize($filename);

            list($size['width'], $size['height']) = getimagesize($filename);
        }
        return $size;
    }

}
